/*
 * @Description  : 工具类
 * @Author       : YiDing Xue
 * @Date         : 2023-01-12
 * @LastEditors  : YiDing Xue
 * @LastEditTime : 2023-03-08
 */
import dayjs from 'dayjs'
import { logDark } from '~/node_modules/naive-ui/es/styles'

/**
 * @desc    格式化时间为 YYY-MM-DD HH:mm:ss
 * @param   {(Object|string|number)} time
 * @param   {string} format
 * @returns {string | null}
 */
export const formatDateTime = (time = undefined, format = 'YYYY-MM-DD HH:mm:ss') => {
  return dayjs(time).format(format)
}

/**
 * @desc  格式化时间为 YYY-MM-DD
 * @param {(Object|string|number)} date
 * @param {string} format
 * @returns
 */
export const formatDate = (date = undefined, format = 'YYYY-MM-DD') => {
  return formatDateTime(date, format)
}

/**
 * 格式化时间
 * @param {String} second 秒
 * @returns mm:ss 格式时间
 */
export const timeFormat = second => {
  let sec = second % 60
  let min = Math.floor(second / 60)
  if (min.toString().length < 2) {
    min = '0' + min
  }
  if (sec.toString().length < 2) {
    sec = '0' + sec
  }
  return min + ':' + sec
}

/**
 * @desc  格式化时间为 mm:ss
 * @param {(Object|string|number)} date
 * @param {string} format
 * @returns
 */
export const formatTime = (date = undefined, format = 'mm:ss') => {
  return formatDateTime(date, format)
}

/**
 * @desc  函数节流
 * @param {Function} fn
 * @param {Number} wait
 * @returns {Function}
 */
export const throttle = (fn, wait) => {
  let context, args
  let previous = 0

  return function () {
    let now = +new Date()
    context = this
    args = arguments
    if (now - previous > wait) {
      fn.apply(context, args)
      previous = now
    }
  }
}

/**
 * @desc  函数防抖
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export const debounce = (method, wait, immediate) => {
  let timeout
  return function (...args) {
    let context = this
    if (timeout) {
      clearTimeout(timeout)
    }
    // 立即执行需要两个条件，一是immediate为true，二是timeout未被赋值或被置为null
    if (immediate) {
      /**
       * 如果定时器不存在，则立即执行，并设置一个定时器，wait毫秒后将定时器置为null
       * 这样确保立即执行后wait毫秒内不会被再次触发
       */
      let callNow = !timeout
      timeout = setTimeout(() => {
        timeout = null
      }, wait)
      if (callNow) {
        method.apply(context, args)
      }
    } else {
      // 如果immediate为false，则函数wait毫秒后执行
      timeout = setTimeout(() => {
        /**
         * args是一个类数组对象，所以使用fn.apply
         * 也可写作method.call(context, ...args)
         */
        method.apply(context, args)
      }, wait)
    }
  }
}

/** 处理上传成功后返回的 JSON 字符串 */
export const handleJsonString = value => {
  let result = JSON.parse(value)
  if (result.code !== 0) {
    $message.error(result.msg)
    return
  }

  return result.data
}

/**
 * @description: 获取浏览器版本
 * @param {*}
 * @return {*}
 */
export const getBrowserInfo = () => {
  const browser = {
    versions: (() => {
      let u = navigator.userAgent
      return {
        // 移动终端浏览器版本信息
        trident: u.indexOf('Trident') > -1, // IE内核
        presto: u.indexOf('Presto') > -1, // opera内核
        webKit: u.indexOf('AppleWebKit') > -1, // 苹果、谷歌内核
        gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') === -1, // 火狐内核
        mobile: !!u.match(/AppleWebKit.*Mobile.*/), // 是否为移动终端
        ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), // ios终端
        android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, // android终端或uc浏览器
        iPhone: u.indexOf('iPhone') > -1, // 是否为iPhone或者QQHD浏览器
        iPad: u.indexOf('iPad') > -1, // 是否iPad
        webApp: u.indexOf('Safari') === -1 // 是否web应该程序，没有头部与底部
      }
    })(),
    language: (navigator.browserLanguage || navigator.language).toLowerCase()
  }
  let ua = navigator.userAgent.toLowerCase() // 获取判断用的对象
  if (ua.match(/MicroMessenger/i) === 'micromessenger') {
    // 在微信中打开
    let isComWx = /wxwork/i.test(navigator.userAgent) // 是否企业微信
    if (isComWx) {
      browser.app = 'wxwork'
    } else {
      browser.app = 'weixin'
    }
  }
  if (browser.versions.mobile) {
    // 判断是否是移动设备打开。browser代码在下面
    if (ua.match(/WeiBo/i) === 'weibo') {
      // 在新浪微博客户端打开
      browser.app = 'weibo'
    } else if (ua.match(/QQ/i) === 'qq') {
      // 在QQ空间打开
      browser.app = 'qq'
    }
  } else {
    // 否则就是PC浏览器打开
    browser.versions.pc = true
  }
  return browser
}

/** 判断是否是微信环境 */
export const isWxBrowser = () => {
  let ua = window.navigator.userAgent.toLowerCase()
  // 判断ua和微信浏览器的标识头是否匹配
  return ua.indexOf('micromessenger') !== -1 || false
}
/**
 * @description: 判断当前环境是否是企业微信
 * @param {*}
 * @return {*}
 */
export function isWorkWxBrowser() {
  const browserInfo = getBrowserInfo()
  return browserInfo.app === 'wxwork'
}
/**
 * @description: 判断当前环境是否是微信手机端环境
 * @param {*}
 * @return {*}
 */
export function isWxMobileBrowser() {
  const browserInfo = getBrowserInfo()
  return browserInfo.app === 'weixin' && browserInfo.versions.mobile === true
}
/**
 * @description: 是否是ios 微信移动端
 * @return {*}
 */
export function isWxIosMobileBrowser() {
  if (!isWxMobileBrowser()) {
    return false
  }
  const browserInfo = getBrowserInfo()
  if (!browserInfo.versions.ios) {
    return false
  }
  return true
}
/**
 * @description: 是否是wap环境，非微信的移动端浏览器
 * @return {*}
 */
export function isWapBrowser() {
  const browserInfo = getBrowserInfo()
  return browserInfo.app !== 'weixin' && browserInfo.versions === 'mobile'
}

export const _debounce = (fn, delay) => {
  delay = delay || 200
  let timer
  return function () {
    let th = this
    let args = arguments
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(function () {
      timer = null
      fn.apply(th, args)
    }, delay)
  }
}

/**
 * @description: 微信自动登录
 * @param {route} 路由信息
 * @return {*}
 */
export const wxAutoLogin = async route => {
  const code = route?.query?.code
  if (!isWxBrowser()) {
    return
  }

  // await window.wxSdkConfigPromise

  if (code) {
    let codeStatus = localStorage.getItem(code)
    if (codeStatus) {
      let parseCodeStatus = JSON.parse(codeStatus)
      if (parseCodeStatus.code === code && new Date() > parseCodeStatus.time) return
    }
    let userInfo = await store.dispatch('getUserInfo').catch(() => {})
    let resp
    if (userInfo && userInfo.registerStatus === 0) {
      // 授权
      resp = await post(`/user/registerWc/${code}`).catch(() => {})
    } else {
      // 登录
      const loading = Toast.loading({
        message: '初始化信息中，请稍候...',
        forbidClick: true,
        loadingType: 'spinner'
      })
      resp = await post(`/user/loginWc/${code}`).catch(() => {})
      loading.clear()
    }
    if (!resp) {
      Toast({
        type: 'info',
        message: '查询当前token失败,请刷新页面后重试',
        duration: 1e3
      })
      window.localStorage.removeItem('h_token')
    } else {
      store.commit('setUserInfo', null)
      await store.dispatch('getUserInfo')
      setToken(resp)
      localStorage.setItem('code', JSON.stringify({ code: route.query.code, time: Date.now() }))
      delete route.query.code
      // router.replace2(route);  // 隐藏掉路由上的code码
    }
  } else {
    // const appid = import.meta.env.VITE_WX_APPID
    // const redirect_uri = encodeURIComponent(window.location.href, 'UTF-8')
    // // snsapi_base （不弹出授权页面，直接跳转，只能获取用户 openid），snsapi_userinfo （弹出授权页面，可通过 openid 拿到昵称、性别、所在地。
    // const scope = 'snsapi_userinfo'
    // const wxAuthorAddress = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=${scope}&state=STATE#wechat_redirect`
    // window.location.replace(wxAuthorAddress)
  }
}

/**
 * @description: 初始化微信相关工具(客服需要)
 * @param {*}
 * @return {*}
 */
export const initWxRelated = ({ debuggerMode = false }) => {
  let isWx = isWxBrowser()
  let isWorkWx = isWorkWxBrowser()
  if (!isWx && !isWorkWx) {
    return
  }
  window.wxSdkConfigPromise = new Promise(async resolve => {
    await loadScript({
      src: 'https://res2.wx.qq.com/open/js/jweixin-1.6.0.js',
      id: 'wxScript'
    })
    const { appId, signature, nonceStr, timestamp } = await getWxsign(window.location.href)
    window.wx.config({
      debug: debuggerMode, // 开启调试模式,调用的所有api的返回值会在客户端alert出来，若要查看传入的参数，可以在pc端打开，参数信息会通过log打出，仅在pc端时才会打印。
      appId, // 必填，公众号的唯一标识
      timestamp, // 必填，生成签名的时间戳
      nonceStr, // 必填，生成签名的随机串
      signature, // 必填，签名
      jsApiList: [
        'updateAppMessageShareData',
        'updateTimelineShareData',
        'onMenuShareWeibo',
        'previewImage',
        'chooseWXPay',
        'scanQRCode',
        'startRecord',
        'stopRecord',
        'translateVoice'
      ], // 必填，需要使用的JS接口列表
      openTagList: ['wx-open-audio'] // 微信开放标签
    })
    window.appId = appId
    let delayTimer
    let delayTime = 5e3
    window.wx.ready(function () {
      clearTimeout(delayTimer)
      resolve({
        appId
      })
      window.wx.checkJsApi({
        jsApiList: ['updateAppMessageShareData'],
        success(res) {
          console.info(res)
        }
      })
    })
    window.wx.error(res => {
      clearTimeout(delayTimer)
      console.error('微信初始化错误')
      console.error(JSON.stringify(res))
    })
    delayTimer = setTimeout(() => {
      resolve({
        appId
      })
    }, delayTime)
  })
}
